home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
007
/
pctekap1.arc
/
DPFILE.ASM
< prev
next >
Wrap
Assembly Source File
|
1986-03-15
|
11KB
|
394 lines
PAGE
TITLE DPFILE
;
; (C)COPYRIGHT 1983 - REAL TIME CONCEPTS, INC.
;
; AUTHOR: THOMAS V. CARTER
;
; PC DOS FILE DUMP UTILITY PROGRAM
;
; ALLOCATE THE STACK WORK AREA
;
STACKS SEGMENT PARA STACK 'STACK'
;
DB 50 DUP('$$')
;
STACKS ENDS
;
PAGE
;
; ALLOCATE THE WORKING STORAGE SEGMENT
;
WSTORE SEGMENT PARA PUBLIC 'DATA'
;
; ALLOCATE THE FILE NAME OPERATOR PROMPT
;
FILNAM DB 'File name = '
DB '$'
;
; ALLOCATE THE BLOCK NUMBER TEXT AND WORK AREAS
;
BLKNUM DB 'Block Number = '
;
BCOUNT DB '0000'
DW 0A0DH
DW 0A0DH
DB '$'
;
; ALLOCATE THE FILE OPEN ERROR ERROR MESSAGE
;
OPNERM DB 'File open error'
DW 0A0DH
DB '$'
;
; ALLOCATE THE FILE NOT FOUND ERROR MESSAGE
;
NOFILE DB 'File not found'
DW 0A0DH
DB '$'
;
; DEFINE CARRIAGE RETURN AND LINE FEED CHARACTERS
;
CRLFLN DW 0A0DH
DB '$'
;
; BINARY TO HEXADECIMAL CONVERSION TABLE
;
ASCIIT DB '0123456789ABCDEF'
;
PAGE
;
; ALLOCATE FORM FEED CHARACTER
;
FMFEED DW 0A0DH
DB 0CH
DB '$'
;
; ALLOCATE THE I/O BUFFER // 512 BYTES PER BLOCK
;
FILBUF DB 512 DUP(' ')
;
;ALLOCATE THE FILESPEC INPUT STRUCTURE
;
INPNAM DB 15
DB 0
DB 15 DUP(' ')
;
; ALLOCATE THE FILE DUMP PRINT LINE
;
DPLINE DB 78 DUP(' ')
DW 0A0DH
;
; ALLOCATE THE HEXADECIMAL BUFFER OFFSET COUNTER
;
HEXCNT DW 0
;
;DEFINE BINARY TO DECIMAL DIVISORS
;
BINDEC DW 1000
DW 100
DW 10
;
WSTORE ENDS
PAGE
;
; PC DOS FILE DUMP UTILITY PROGRAM
;
CODSEG SEGMENT PARA PUBLIC 'CODE'
;
DPFILE PROC FAR
ASSUME CS:CODSEG ;CS = CODE SGEMENT
ASSUME DS:WSTORE ;DS = DATA SEGMENT
ASSUME SS:STACKS ;SS = STACK SEGMENT
;
; INITIALIZE THE PROGRAM ENVIRONMENT
;
PUSH DS ;SAVE PROGRAM PREFIX SEGMENT
SUB AX,AX ;AX = ZERO // SET FOR STACK
MOV BP,AX ;BP = ZERO // STACK START
MOV [BP],AX ;SETUP BLOCK NUMBER ZERO
PUSH AX ;PUSH AX (ZERO) ON STACK
MOV AX,WSTORE ;AX = WORKING STORAGE SEGMENT
MOV DS,AX ;DS = WORKING STORAGE SEGMENT
;
; DISPLAY THE FILE NAME PROMPT TO THE OPERATOR
;
MOV DX,OFFSET FILNAM ;DX = PROMPT OFFSET ADDRESS
MOV AH,09H ;AH = 9 = DISPLAY PROMPT
INT 21H ;CALL DOS FOR SERVICE
;
; ACQUIRE THE OPERATOR RESPONSE // FILESPEC
;
MOV DX,OFFSET INPNAM ;DX = SEGMENT OFFSET ANSWER
MOV AH,0AH ;AH = A = KEYBOARD INPUT
INT 21H ;CALL DOS FOR SERVICE
;
; SEND CARRIAGE RETURN AND LINE FEED FOR APPEARANCES
;
MOV DX,OFFSET CRLFLN ;DX = CR/LF OFFSET ADDRESS
MOV AH,09H ;AH = 9 = DISPLAY CR AND LF
INT 21H ;CALL DOS FOR SERVICE
;
; PARSE THE OPERATOR SPECIFIED FILESPEC
;
MOV SI,OFFSET INPNAM+2 ;SI = FILESPEC OFFSET ADDRESS
MOV DI,5CH ;DI = 1ST PROGRAM PREFIX FCB
SUB AL,AL ;AL = ZERO
MOV AH,29H ;PARSE THE RECEIVED FILE NAME
INT 21H ;CALL DOS FOR SERVICE
PAGE
;
; FILESPEC PARSED (1ST PROGRAM PREFIX FCB) // OPEN THE FILE
;
PUSH DS ;SAVE THE DATA SEGMENT REGISTER
;
MOV DX,5CH ;DX = 1ST PROGRAM PREFIX FCB
MOV AX,ES ;AX = PROGRAM PREFIX SEGMENT
MOV DS,AX ;DS = PROGRAM PREFIX SEGMENT
MOV AH,0FH ;AH = F = OPEN THE FILE
INT 21H ;CALL DOS FOR SERVICE
;
POP DS ;RESTORE DATA SEGMENT REGISTER
;
CMP AL,0 ;AL = OPEN FILE RETURN STATUS
JE DPF010 ;BRANCH IF SUCCESSFUL OPEN
;
; FILE OPEN ERROR - NOTIFY THE OPERATOR AND TERMINATE
;
MOV DX,OFFSET OPNERM ;DX = OPEN ERROR MESSAGE OFFSET
MOV AH,09H ;AH = 9 = DISPLAY ERROR MESSAGE
INT 21H ;CALL DOS FOR SERVICE
RET ;TERMINATE PROGRAM EXECUTION
;
; SEND CARRIAGE RETURN AND LINE FEED FOR APPEARANCES
;
DPF010:
MOV DX,OFFSET CRLFLN ;DX = CR/LF OFFSET ADDRESS
MOV AH,09H ;AH = 9 = DISPLAY CR AND LF
INT 21H ;CALL DOS FOR SERVICE
;
; SETUP THE DATA TRANSFER ADDRESS (DTA)
;
MOV DX,OFFSET FILBUF ;DX = I/O BUFFER OFFSET ADDRESS
MOV AH,1AH ;AH = 1A = SETUP DTA
INT 21H ;CALL DOS FOR SERVICE
;
; INITIALIZE THE 1ST PROGRAM PREFIX FILE CONTROL BLOCK
;
MOV DI,5CH ;DI = FCB OFFSET ADDRESS
MOV AX,512 ;AX = 512 = RECORD SIZE
MOV ES:[DI+14],AX ;SETUP LOGICAL RECORD SIZE
SUB AX,AX ;AX = ZERO
MOV ES:[DI+32],AX ;SETUP RANDOM RECORD NUMBER
MOV ES:[DI+34],AX ;SETUP RANDOM RECORD NUMBER
MOV ES:[DI+36],AL ;SETUP RANDOM RECORD NUMBER
PAGE
;
; SETUP TO CLEAR THE FILE I/O BUFFER
;
DPF020:
MOV CX,256 ;CX = LOOP CONTROL COUNTER
MOV DI,OFFSET FILBUF ;DI = I/O BUFFER OFFSET ADDRESS
SUB AX,AX ;AX = ZEROS
;
; SET THE CONTENTS OF THE I/O BUFFER TO BINARY ZEROS
;
DPF030:
MOV [DI],AX ;SET I/O BUFFER TO BINARY ZEROS
ADD DI,2 ;INCREMENT DI TO NEXT WORD
LOOP DPF030 ;LOOP FOR ALL BUFFER WORDS
;
; READ EACH 512 BYTE BLOCK OF THE FILE // RANDOM BLOCK READ
;
PUSH DS ;SAVE DATA SEGMENT REGISTER
MOV AX,ES ;AX = PROGRAM PREFIX SEGMENT
MOV DS,AX ;DS = PROGRAM PREFIX SEGMENT
MOV DX,5CH ;DX = 1ST PROGRAM PREFIX FCB
MOV CX,1 ;CX = NUMBER OF RECORDS
MOV AH,27H ;AH = 27 = RANDOM BLOCK READ
INT 21H ;CALL DOS FOR SERVICE
POP DS ;RESTORE DATA SEGMENT REGISTER
;
CMP AL,0 ;VERIFY DISK READ COMPLETION
JE DPF040 ;BRANCH IF SUCCESSFUL READ
CMP CX,0 ;CHECK FOR PARTIAL BLOCK
JNE DPF040 ;BRANCH IF DATA IN BUFFER
;
RET ;TERMINATE PROGRAM EXECUTION
;
; CONVERT DATA TO DISPLAYABLE ASCII AND DISPLAY
;
DPF040:
MOV DI,OFFSET BCOUNT ;DI = BLOCK COUNT ADDRESS
MOV AX,[BP] ;AX = CURRENT BLOCK COUNT
INC AX ;INCREMENT BLOCK COUNT
MOV [BP],AX ;SAVE NEW BLOCK COUNT
DEC AX ;DECREMENT BLOCK COUNT
CALL BDCONV ;BINARY TO DECIMAL CONVERSION
MOV DX,OFFSET BLKNUM ;DX = BLOCK NUMBER MESSAGE
MOV AH,09H ;AH = 9 = DISPLAY BLOCK NUMBER
INT 21H ;CALL DOS FOR SERVICE
MOV SI,OFFSET FILBUF ;SI = FILE I/O BUFFER ADDRESS
MOV DI,OFFSET DPLINE+12 ;DI = HEXADECIMAL DISPLAY AREA
MOV BP,OFFSET DPLINE+62 ;BP = ASCII DISPLAY AREA
MOV CX,32 ;CX = NUMBER OF 16 BYTE LINES
PUSH CX ;SAVE CX REGISTER ON THE STACK
MOV CX,16 ;CONVERSION LOOP COUNTER
;
PAGE
;
; CONVERT A BYTE OF INPUT DATA TO HEXADECIMAL
;
DPF050:
CMP CX,8 ;HALF OF LINE CONVERTED?
JNE DPF060 ;BRANCH TO CONTINUE - NOT HALF
DEC DI ;DECREMENT LINE POSITION INDEX
MOV AL,'-' ;MOVE A DASH TO SEPARATE HALFS
MOV [DI],AL ;MOVE A DASH TO SEPARATE HALFS
INC DI ;INCREMENT LINE POSITION INDEX
;
; SAVE CX ON THE STACK AND PROCESS NEXT BYTE
;
DPF060:
PUSH CX ;SAVE CONVERSION LOOP COUNTER
MOV CL,4 ;CL = 4 = SHIFT COUNTER
MOV AL,[SI] ;AL = FILE BUFFER CHARACTER
MOV AH,AL ;AH = FILE BUFFER CHARACTER
CMP AH,20H ;COMPARE AH AN ASCII " "
JL DPF070 ;BRANCH IF UNDISPLAYABLE
CMP AH,7EH ;COMPARE AH TO ASCII "~"
JNG DPF080 ;BRANCH IF DISPLAYABLE
;
; SET AH TO AN ASCII PERIOD // NON-DISPLAYABLE CHARACTER
;
DPF070:
MOV AH,"." ;AH = AN ASCII PERIOD
;
; AH CONTAINS THE DISPLAYABLE ASCII CHARACTER
;
DPF080:
MOV DS:[BP],AH ;MOVE CHARACTER TO ASCII AREA
SUB AH,AH ;AH = ZEROS // SET FOR CONVERT
SHL AX,CL ;POSITION UPPER CL BITS OF AL
SHR AL,CL ;POSITION LOWER CL BITS OF AL
XCHG AL,AH ;EXCHANGE CONTENTS OF AL AND AH
PUSH AX ;SAVE CONTENTS OF AX ON STACK
MOV BX,OFFSET ASCIIT ;BX = ASCII TABLE ADDRESS
XLAT ASCIIT ;CONVERT CHARACTER TO HEX
MOV [DI],AL ;MOVE CHARACTER TO DISPLAY LINE
INC DI ;INCREMENT STORAGE INDEX
POP AX ;RESTORE ORIGINAL AX CONTENTS
MOV CL,8 ;CL = 8 = SHIFT COUNTER
SHR AX,CL ;POSITION UPPER 8 BITS
XLAT ASCIIT ;CONVERT CHARACTER TO HEX
MOV [DI],AL ;MOVE CHARACTER TO DISPLAY LINE
ADD DI,2 ;INCREMENT DI FOR NEXT BYTE
INC SI ;INCREMENT SI FOR NEXT BYTE
INC BP ;INCREMENT BP FOR NEXT BYTE
POP CX ;RESTORE LOOP CONTROL COUNTER
LOOP DPF050 ;BRANCH TO CONVERT FULL LINE
;
PAGE
;
; CONVERT AND SETUP RELATIVE BUFFER OFFSET
;
MOV AX,HEXCNT ;AX = CURRENT BUFFER OFFSET
MOV DI,OFFSET DPLINE+6 ;DI = DISPLAY LINE OFFSET
PUSH SI ;SAVE BUFFER INDEX ON STACK
CALL BDCONV ;BINARY TO DECIMAL CONVERSION
POP SI ;RESTORE BUFFER INDEX
MOV DI,OFFSET DPLINE ;DI = DISPLAY LINE OFFSET
MOV AX,HEXCNT ;AX = CURRENT BUFFER OFFSET
MOV CX,4 ;CX = LOOP COUNTER (4 BYTES)
;
; CONVERT HEXADECIMAL TO ASCII // BUFFER OFFSET
;
DPF090:
PUSH CX ;SAVE LOOP COUNTER ON STACK
MOV CL,4 ;CL = 4 = SHIFT COUNTER
PUSH AX ;SAVE CURRENT BUFFER OFFSET
AND AX,0F000H ;ISOLATE UPPER NIBBLE // 4 BITS
XCHG AL,AH ;EXCHANGE VALUES IN AL AND AH
SHR AL,CL ;POSITION 4-BIT NIBBLE
XLAT ASCIIT ;CONVERT TO HEXADECIMAL BYTE
MOV [DI],AL ;STORE CONVERTED BYTE // HEX
INC DI ;INCREMENT BYTE STORAGE INDEX
POP AX ;RESTORE CONTENTS TO AX
SHL AX,CL ;POSITION NEXT 4-BIT NIBBLE
POP CX ;RESTORE THE LOOP COUNTER
LOOP DPF090 ;LOOP TO CONVERT ALL NIBBLES
;
; DISPLAY THE LAST LINE CONVERTED
;
ADD HEXCNT,16 ;UPDATE HEX OFFSET COUNTER
MOV BX,OFFSET DPLINE ;BX = HEXADECIMAL DISPLAY AREA
MOV CX,80 ;CX = DISPLAY LINE BYTE COUNT
;
; DISPLAY A CONVERTED BYTE OF DATA
;
DPF100:
MOV DL,[BX] ;DL = CONVERTED DATA BYTE
INC BX ;INCREMENT BX TO NEXT BYTE
MOV AH,02H ;AH = 2 = DISPLAY CHARACTER
INT 21H ;CALL DOS FOR SERVICE
LOOP DPF100 ;BRANCH TO DISPLAY NEXT BYTE
POP CX ;RESTORE BLOCK COUNTER
LOOP DPF110 ;BRANCH TO PRINT NEXT LINE
MOV HEXCNT,0 ;RESET THE HEX OFFSET COUNTER
MOV DX,OFFSET FMFEED ;DX = CR, LF, AND FF BUFFER
MOV AH,09H ;AH = 9 = WRITE DATA TO DISPLAY
INT 21H ;CALL DOS FOR SERVICE
SUB BP,BP ;BP = ZERO - FOR BLOCK NUMBER
JMP DPF020 ;BRANCH TO READ NEXT BLOCK
PAGE
;
; CONVERT AND DISPLAY NEXT 16 BYTES OF DATA
;
DPF110:
PUSH CX ;SAVE CONTENTS OF LINE COUNTER
MOV AX,2020H ;AX = 2 ASCII SPACES
MOV CX,39 ;CX = NUMBER OF WORDS TO SET
MOV DI,OFFSET DPLINE ;DI = DISPLAY LINE OFFSET
;
; MOVE ASCII SPACES TO THE DISPLAY LINE BUFFER
;
DPF120:
MOV [DI],AX ;MOVE SPACES TO DISPLAY LINE
ADD DI,2 ;INCREMENT DI BY WORDS
LOOP DPF120 ;BRANCH TO SET ALL WORDS
;
MOV DI,OFFSET DPLINE+12 ;DI = HEXADECIMAL DISPLAY AREA
MOV BP,OFFSET DPLINE+62 ;BP = ASCII DISPLAY AREA
MOV CX,16 ;RESET LINE CONVERSION COUNTER
JMP DPF050 ;BRANCH TO CONVERT NEXT LINE
;
DPFILE ENDP
PAGE
;
; BINARY TO DECIMAL (ASCII) CONVERSION
;
BDCONV PROC NEAR
MOV CX,3 ;CX = LOOP COUNTER
SUB SI,SI ;SI = ZERO // FOR INDEX
;
; BINARY TO DECIMAL CONVERSION LOOP
;
BDC010:
SUB DX,DX ;DX = ZERO // FOR DIVISION
DIV BINDEC[SI] ;DIVIDE FOR DECIMAL DIGIT
ADD AL,30H ;ADD 30H FOR ASCII NUMBER
MOV [DI],AL ;STORE ASCII NUMERIC DIGIT
INC DI ;INCREMENT FOR NEXT NUMBER
ADD SI,2 ;INCREMENT SI FOR NEXT NUMBER
MOV AX,DX ;RESTORE REMAINDER TO AX
LOOP BDC010 ;BRANCH TO CONVERT ALL DATA
;
ADD AL,30H ;ADD 30H FOR ASCII
MOV [DI],AL ;STORE ASCII NUMERIC DIGIT
RET ;RETURN TO CALLER
;
BDCONV ENDP
;
CODSEG ENDS
END DPFILE